from twisted.words.protocols.jabber import jid, xmlstream
from twisted.internet import reactor
from twisted.python import log
from wokkel import muc
import socket

import common

master_user = 'master'
master_resource = 'master'
                
class SlaveMucProtocol( common.CommonMucProtocol ):
    pass

class SlaveMessageProtocol( common.CommonMessageProtocol ):
    pass

class SlavePresenceProtocol( common.CommonPresenceProtocol ):
    pass

class SlaveRPCProtocol( common.RPCProtocol ):
    
    def onMethodCall(self, iq):
        if iq.getAttribute('from') != self.my_parent.master_jid.full():
            return
        
        common.RPCProtocol.onMethodCall(self, iq)
        
    
       
class SlaveRosterProtocol( common.CommonRosterProtocol ):
        
    def getRosterResponse(self, roster):
        common.CommonRosterProtocol.getRosterResponse(self,roster)
        
        user_status = self.my_parent.rtr_client.getUserStatus( jid.JID( master_user + '@' + self.my_parent.jid.host ) )
        if not user_status or ( not user_status == 'both' and not user_status == 'from' ):
            self.subscribeToMaster()   
        
    def subscribeToMaster(self):
        # add master to roster
        
        def addMasterResponse( response ):
            print 'addMasterResponse received'
            
            if response.attributes['type'] == 'result':
                self.my_parent.pre_client.subscribe( jid.JID( master_user + '@' + self.my_parent.jid.host ) )
        
        self.addItem( jid.JID( master_user + '@' + self.my_parent.jid.host ) ).addCallback( addMasterResponse ).addErrback( log.err )
        
class SlaveClient( object ):
                
    def __init__( self, user, resource, password, master, server, port = 5222, trigger_config = False ):
        
        self.server = server
        self.port = int( port )
        self.master_jid = jid.JID( master )
       
        self.jid = jid.JID( user + '@' + server + "/" + resource )
        self.factory = common.CommonClientFactory(self, password)
        self.factory.streamManager.logTraffic = True
    
        self.muc_client = SlaveMucProtocol( self )
        self.muc_client.setHandlerParent( self.factory.streamManager )
        
        self.msg_client = SlaveMessageProtocol( self )
        self.msg_client.setHandlerParent( self.factory.streamManager )
    
        self.pre_client = SlavePresenceProtocol( self )
        self.pre_client.setHandlerParent( self.factory.streamManager )
        self.pre_client.available()
        #self.pre_client.addPresenceTrigger( self.master_jid, 'available', self.registerWithMaster )
        
        self.rtr_client = SlaveRosterProtocol( self )
        self.rtr_client.setHandlerParent( self.factory.streamManager )
        
        self.rpc_client = SlaveRPCProtocol( self )
        self.rpc_client.setHandlerParent( self.factory.streamManager )
        self.rpc_client.subscribeMethod( 'registerClient', self.rpc_loadAvg )
        
        if trigger_config:
            self.trigger_handler = common.TriggerHandler( self, trigger_config )
            self.trigger_handler.setHandlerParent( self.factory.streamManager )
            
            new_trigger = common.XpathTrigger( self.trigger_handler, { 
                                                                      'name': 'master presence trigger',
                                                                      'repeat': True,
                                                                      'xpath': '/{jabber:client}presence[@from="%s" and ( @type="available" or not( @type ) )]' % self.master_jid.full(),
                                                                      'action': {'type': 'function',
                                                                                 'function': self.registerWithMaster,
                                                                                 }
                                                                      } )
            
            self.trigger_handler.addXpathTrigger( new_trigger )
            
        reactor.connectTCP( self.server, self.port, self.factory )
        
    def registerWithMaster(self, trigger):
        my_hostname = socket.gethostname() 
        my_ip       = socket.gethostbyname( my_hostname )
        
        self.rpc_client.callMethod( self.master_jid, 'registerClient', [ my_ip, my_hostname ] )
        
    def test_func(self, trigger, a, b ):
        print 'test_func'
        print trigger.name
        print a
        
    """ RPC calls """
    def rpc_loadAvg(self):
        import os
        
        if os.name == 'posix':
            print os.getloadavg()
            return os.getloadavg()
        elif os.name == 'nt':
            return False
        else:
            return False
        